import { computed, reactive, toRefs } from "vue"
import { defineStore } from "pinia";
import { RouteLocationNormalizedLoaded, RouteRecordNormalized } from "vue-router";
import router from "@/router";

interface ViewTagStates {
  viewTags: RouteLocationNormalizedLoaded[];
  tag: RouteLocationNormalizedLoaded;
  initTagsData: RouteLocationNormalizedLoaded[];
}

export const useViewTagStore = defineStore("viewTagStore", () => {
  const state = reactive<ViewTagStates>({
    viewTags: [],
    tag: <RouteLocationNormalizedLoaded>{},
    initTagsData: <RouteLocationNormalizedLoaded[]>[],
  });

  const SET_INIT_TAGS = (viewTags: RouteLocationNormalizedLoaded[]) => {
    state.initTagsData = viewTags;
  };

  const ADD_VIEW_TAG = (viewTag: RouteLocationNormalizedLoaded) => {
    const index = state.viewTags.findIndex((f) => f.path === viewTag.path);
    index === -1 && state.viewTags.push(viewTag);
  };

  const SET_TAG = (viewTag: RouteLocationNormalizedLoaded) => {
    state.tag = viewTag;
  };

  const DEL_TAG = (viewTag: RouteLocationNormalizedLoaded) => {
    const index = state.viewTags.findIndex((f) => f.path === viewTag.path);

    index !== -1 && state.viewTags.splice(index, 1);
  };

  const CLOSE_ALL_TAG = () => {
    state.viewTags = [];
  };

  const initTags = () => {
    const getAffixRoutes = (routes: RouteRecordNormalized[]) => {
      let rts: RouteLocationNormalizedLoaded[] = [];
      routes.forEach((r) => {
        if (r.meta && r.meta.affix && !r.meta.noTag) {
          rts.push({
            path: r.path,
            name: r.name,
            meta: { ...r.meta },
            query: {},
            params: {},
            matched: [],
            hash: "",
            redirectedFrom: undefined,
            fullPath: r.path,
          });

          if (r.children) {
            rts = [...rts, ...getAffixRoutes(r.children as RouteRecordNormalized[])];
          }
        }
      });
      return rts;
    };

    SET_INIT_TAGS(getAffixRoutes(router.getRoutes()));
  };

  const addViewTag = (viewTag: RouteLocationNormalizedLoaded) => {
    ADD_VIEW_TAG(viewTag);
  };

  const setTag = (viewTag: RouteLocationNormalizedLoaded) => {
    SET_TAG(viewTag);
  };

  const delTag = (viewTag: RouteLocationNormalizedLoaded) => {
    DEL_TAG(viewTag);
  };

  const closeAllTag = () => {
    CLOSE_ALL_TAG();
  };

  const getTag = computed(() => state.tag || {});

  const getCacheNames = computed(() => [...state.initTagsData, ...state.viewTags].filter(f => f.meta?.cache).map(m => m.name));

  return {
    ...toRefs(state),
    initTags,
    addViewTag,
    setTag,
    delTag,
    closeAllTag,
    getTag,
    getCacheNames,
  }
});